package com.guducat.collegeWeb.mapper;

import com.guducat.collegeWeb.entity.Article;
import org.apache.ibatis.annotations.*;

import java.time.ZonedDateTime;
import java.util.List;

/**
 * 文章数据访问接口
 * 使用MyBatis注解方式实现SQL映射
 */
@Mapper
public interface ArticleMapper {
    // 基本CRUD操作
    /**
     * 根据新闻ID查询文章
     * @param news_id 新闻ID
     * @return 文章对象
     */
    @Results(id = "articleResultMap", value = {
        @Result(property = "newsId", column = "news_id", id = true),
        @Result(property = "category", column = "category"),
        @Result(property = "title", column = "title"),
        @Result(property = "pubTime", column = "pub_time"),
        @Result(property = "contentHtml", column = "content_html"),
        @Result(property = "contentText", column = "content_text"),
        @Result(property = "url", column = "url"),
        @Result(property = "crawlTime", column = "crawl_time"),
        @Result(property = "section", column = "section")
    })
    @Select("SELECT * FROM news WHERE news_id = #{news_id}")
    Article selectByNewsId(int news_id);

    /**
     * 插入文章
     * @param article 文章对象
     * @return 影响行数
     */
    @Insert("INSERT INTO news (news_id, category, title, pub_time, content_html, content_text, url, crawl_time, section) " +
           "VALUES (#{newsId}, #{category}, #{title}, #{pubTime}, #{contentHtml}, #{contentText}, #{url}, #{crawlTime}, #{section})")
    int insert(Article article);

    /**
     * 根据新闻ID更新文章
     *
     * @param article 文章对象
     */
    @Update("UPDATE news SET category = #{category}, title = #{title}, pub_time = #{pubTime}, " +
           "content_html = #{contentHtml}, content_text = #{contentText}, url = #{url}, section = #{section} " +
           "WHERE news_id = #{newsId}")
    void updateByNewsId(Article article);

    /**
     * 根据新闻ID删除文章
     * @param news_id 新闻ID
     * @return 影响行数
     */
    @Delete("DELETE FROM news WHERE news_id = #{news_id}")
    int deleteByNewsId(int news_id);

    // 内容管理相关方法
    /**
     * 插入文章并自动生成ID
     *
     * @param article 文章对象
     */
    @Insert("INSERT INTO news (category, title, pub_time, content_html, content_text, url, section) " +
           "VALUES (#{category}, #{title}, #{pubTime}, #{contentHtml}, " +
           "REGEXP_REPLACE(#{contentHtml}, '<[^>]+>', ''), #{url}, #{section})")
    @Options(useGeneratedKeys = true, keyProperty = "newsId")
    void insertArticle(Article article);

    /**
     * 插入文章并使用指定的ID
     *
     * @param article 文章对象（包含newsId）
     */
    @Insert("INSERT INTO news (news_id, category, title, pub_time, content_html, content_text, url, crawl_time, section) " +
           "VALUES (#{newsId}, #{category}, #{title}, #{pubTime}, #{contentHtml}, " +
           "REGEXP_REPLACE(#{contentHtml}, '<[^>]+>', ''), #{url}, #{crawlTime}, #{section})")
    void insertArticleWithId(Article article);

    /**
     * 检查文章ID是否已存在
     * @param newsId 文章ID
     * @return 存在返回true，不存在返回false
     */
    @Select("SELECT COUNT(*) FROM news WHERE news_id = #{newsId}")
    boolean existsById(int newsId);

    /**
     * 更新文章内容
     *
     * @param article 文章对象
     */
    @Update("UPDATE news SET category = #{category}, title = #{title}, content_html = #{contentHtml}, " +
           "content_text = REGEXP_REPLACE(#{contentHtml}, '<[^>]+>', ''), section = #{section} " +
           "WHERE news_id = #{newsId}")
    void updateArticle(Article article);

    /**
     * 删除文章
     *
     * @param news_id 新闻ID
     */
    @Delete("DELETE FROM news WHERE news_id = #{news_id}")
    void deleteArticle(int news_id);

    // 查询相关方法
    /**
     * 根据分类查询文章列表
     * @param category 分类
     * @return 文章列表
     */
    @ResultMap("articleResultMap")
    @Select("SELECT * FROM news WHERE category = #{category} ORDER BY pub_time DESC")
    List<Article> selectByCategory(String category);

    /**
     * 查询最新文章
     * @param limit 限制数量
     * @return 文章列表
     */
    @ResultMap("articleResultMap")
    @Select("SELECT * FROM news ORDER BY pub_time DESC LIMIT #{limit}")
    List<Article> selectLatestNews(int limit);

    /**
     * 根据时间范围查询文章
     * @param start 开始时间
     * @param end 结束时间
     * @return 文章列表
     */
    @ResultMap("articleResultMap")
    @Select("SELECT * FROM news WHERE pub_time BETWEEN #{start} AND #{end} ORDER BY pub_time DESC")
    List<Article> selectByTimeRange(ZonedDateTime start, ZonedDateTime end);

    /**
     * 根据分类分页查询文章
     * @param category 分类
     * @param pageSize 每页记录数
     * @param offset 偏移量
     * @return 文章列表
     */
    @ResultMap("articleResultMap")
    @Select("SELECT * FROM news WHERE category = #{category} ORDER BY pub_time DESC LIMIT #{pageSize} OFFSET #{offset}")
    List<Article> selectByCategoryWithPage(@Param("category") String category, @Param("pageSize") int pageSize, @Param("offset") int offset);

    /**
     * 查询分类文章总数
     * @param category 分类
     * @return 文章总数
     */
    @Select("SELECT COUNT(*) FROM news WHERE category = #{category}")
    long countByCategory(@Param("category") String category);

    /**
     * 分页查询最新文章
     * @param pageSize 每页记录数
     * @param offset 偏移量
     * @return 文章列表
     */
    @ResultMap("articleResultMap")
    @Select("SELECT * FROM news ORDER BY pub_time DESC LIMIT #{pageSize} OFFSET #{offset}")
    List<Article> selectLatestNewsWithPage(@Param("pageSize") int pageSize, @Param("offset") int offset);

    /**
     * 查询文章总数
     * @return 文章总数
     */
    @Select("SELECT COUNT(*) FROM news")
    long countAll();

    /**
     * 根据关键词分页查询文章
     * @param keyword 关键词
     * @param pageSize 每页记录数
     * @param offset 偏移量
     * @return 文章列表
     */
    @ResultMap("articleResultMap")
    @Select("SELECT * FROM news WHERE title LIKE CONCAT('%', #{keyword}, '%') OR content_text LIKE CONCAT('%', #{keyword}, '%') ORDER BY pub_time DESC LIMIT #{pageSize} OFFSET #{offset}")
    List<Article> selectByKeywordWithPage(@Param("keyword") String keyword, @Param("pageSize") int pageSize, @Param("offset") int offset);

    /**
     * 查询关键词文章总数
     * @param keyword 关键词
     * @return 文章总数
     */
    @Select("SELECT COUNT(*) FROM news WHERE title LIKE CONCAT('%', #{keyword}, '%') OR content_text LIKE CONCAT('%', #{keyword}, '%')")
    long countByKeyword(@Param("keyword") String keyword);

    /**
     * 根据section筛选文章
     * @param section 学院/教务处等行政机构信息
     * @param pageSize 每页记录数
     * @param offset 偏移量
     * @return 文章列表
     */
    @ResultMap("articleResultMap")
    @Select("SELECT * FROM news WHERE section = #{section} ORDER BY pub_time DESC LIMIT #{pageSize} OFFSET #{offset}")
    List<Article> selectBySectionWithPage(@Param("section") String section, @Param("pageSize") int pageSize, @Param("offset") int offset);

    /**
     * 查询section文章总数
     * @param section 学院/教务处等行政机构信息
     * @return 文章总数
     */
    @Select("SELECT COUNT(*) FROM news WHERE section = #{section}")
    long countBySection(@Param("section") String section);

    /**
     * 多条件搜索文章（分页）
     * @param keyword 关键词（可为null）
     * @param category 分类（可为null）
     * @param section 学院（可为null）
     * @param pageSize 每页记录数
     * @param offset 偏移量
     * @return 文章列表
     */
    @ResultMap("articleResultMap")
    @Select("<script>" +
            "SELECT * FROM news WHERE 1=1 " +
            "<if test='keyword != null and keyword != \"\"'>" +
            "AND (title LIKE CONCAT('%', #{keyword}, '%') OR content_text LIKE CONCAT('%', #{keyword}, '%')) " +
            "</if>" +
            "<if test='category != null and category != \"\"'>" +
            "AND category = #{category} " +
            "</if>" +
            "<if test='section != null and section != \"\"'>" +
            "AND section = #{section} " +
            "</if>" +
            "ORDER BY pub_time DESC LIMIT #{pageSize} OFFSET #{offset}" +
            "</script>")
    List<Article> searchWithMultipleConditions(
            @Param("keyword") String keyword,
            @Param("category") String category,
            @Param("section") String section,
            @Param("pageSize") int pageSize,
            @Param("offset") int offset
    );

    /**
     * 多条件搜索文章总数
     * @param keyword 关键词（可为null）
     * @param category 分类（可为null）
     * @param section 学院（可为null）
     * @return 文章总数
     */
    @Select("<script>" +
            "SELECT COUNT(*) FROM news WHERE 1=1 " +
            "<if test='keyword != null and keyword != \"\"'>" +
            "AND (title LIKE CONCAT('%', #{keyword}, '%') OR content_text LIKE CONCAT('%', #{keyword}, '%')) " +
            "</if>" +
            "<if test='category != null and category != \"\"'>" +
            "AND category = #{category} " +
            "</if>" +
            "<if test='section != null and section != \"\"'>" +
            "AND section = #{section} " +
            "</if>" +
            "</script>")
    long countWithMultipleConditions(
            @Param("keyword") String keyword,
            @Param("category") String category,
            @Param("section") String section
    );

}
